package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.IsDefaultEnum;
import cn.huiyunche.base.service.interfaces.BAreaService;
import cn.huiyunche.base.service.interfaces.UserAddressService;
import cn.huiyunche.base.service.interfaces.UserService;
import cn.huiyunche.base.service.mappers.BAreaMapper;
import cn.huiyunche.base.service.mappers.SUserAddrMapper;
import cn.huiyunche.base.service.model.BArea;
import cn.huiyunche.base.service.model.BAreaExample;
import cn.huiyunche.base.service.model.SUserAddr;
import cn.huiyunche.base.service.model.SUserAddrExample;
import cn.huiyunche.base.service.vo.Result;
import cn.huiyunche.base.service.vo.SUserAddrVo;
import cn.huiyunche.base.service.vo.UserAddressVo;
import cn.huiyunche.base.service.vo.UserVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.alibaba.fastjson.JSON;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service

public class UserAddressServiceImpl implements UserAddressService {

    private static final Logger logger = LoggerFactory.getLogger(UserAddressServiceImpl.class);

    @Autowired
    private SUserAddrMapper sUserAddrMapper = null;

    @Autowired
    private UserService userService = null;

    @Autowired
    private BAreaService bAreaService = null;

    @Autowired
    private BAreaMapper bAreaMapper = null;

    private BAreaMapper getBAreaMapper() {
        return this.bAreaMapper;
    }

    @Override
    public Result<Integer> delUserAddress(Long id) throws Exception {
        logger.info("UserAddressServiceImpl.delUserAddress param : {}", id);
        Result<Integer> result = new Result<>(true, "删除成功!");
        try {
            result.setData(this.getSUserAddrMapper().deleteByPrimaryKey(id));
        } catch (Exception e) {
            throw new BusinessException("删除失败!");
        }
        return result;
    }

    @Override
    public Long addUserAddress(UserAddressVo userAddressVo) throws Exception {
        logger.info("UserAddressServiceImpl.addUserAdderss param : {}", userAddressVo);
        UserVo user = this.getUserService().getCurrentUserVo();
        userAddressVo.setUserid(user.getId());
        SUserAddr ua = buildUserAddress(userAddressVo);
        SUserAddrExample search = new SUserAddrExample();
        SUserAddrExample.Criteria uaCriteria = search.createCriteria();
        uaCriteria.andUserIdEqualTo(user.getId());
        uaCriteria.andAddressTypeEqualTo(userAddressVo.getAddresstype());
        uaCriteria.andIsVeneerEqualTo(ua.getIsVeneer());
        int count = this.getSUserAddrMapper().countByExample(search);
        // 如果当前用户只有一条常用地址信息，则设置为默认地址
        if (count == 0) {
            ua.setIsDefault(IsDefaultEnum.T.getValue());
        } else {
            ua.setIsDefault(IsDefaultEnum.F.getValue());
        }
        this.getSUserAddrMapper().insertSelective(ua);
        return ua.getId();
    }

    @Override
    public int upateUserAddress(UserAddressVo userAddressVo) throws Exception {
        logger.info("upateUserAddress service param : {}", userAddressVo);
        UserVo user = this.getUserService().getCurrentUserVo();
        userAddressVo.setUserid(user.getId());
        userAddressVo.setUpdatetime(new Date());
        logger.info("addUserAdderss userid : {}", user.getId());
        return this.getSUserAddrMapper().updateByPrimaryKeySelective(buildUserAddress(userAddressVo));
    }

    @Override
    public List<SUserAddr> selectUserAddress(String addressType, Boolean isVeneer) throws Exception {
        logger.info("selectUserAddress service params : {}, {}", addressType, isVeneer);
        UserVo user = this.getUserService().getCurrentUserVo();
        logger.info("selectUserAddress userid : {}", user.getId());
        SUserAddrExample search = new SUserAddrExample();
        SUserAddrExample.Criteria userAddress = search.createCriteria();
        userAddress.andUserIdEqualTo(user.getId());
        userAddress.andAddressTypeEqualTo(addressType);

        if (null == isVeneer) {
            userAddress.andIsVeneerEqualTo(false);
        } else {
            userAddress.andIsVeneerEqualTo(isVeneer);
        }

        search.setOrderByClause("is_default DESC,update_time DESC");
        return this.getSUserAddrMapper().selectByExample(search);
    }

    @Override
    public int updateDefaultAddressById(Long id, Boolean isVeneer) throws Exception {
        logger.info("updateDefaultAddressById service param : {}", id);

        SUserAddr record = this.getSUserAddrMapper().selectByPrimaryKey(id);
        record.setUpdateTime(new Date());
        record.setIsDefault(IsDefaultEnum.T.getValue());

        // 设置该类型的地址都为不默认
        UserVo userVo = this.getUserService().getCurrentUserVo();
        SUserAddrExample search = new SUserAddrExample();
        SUserAddrExample.Criteria usCriteria = search.createCriteria();
        usCriteria.andUserIdEqualTo(userVo.getId());
        usCriteria.andAddressTypeEqualTo(record.getAddressType());
        if (null == isVeneer) {
            usCriteria.andIsVeneerEqualTo(false);
        } else {
            usCriteria.andIsVeneerEqualTo(isVeneer);
        }
        List<SUserAddr> userAddrList = this.getSUserAddrMapper().selectByExample(search);
        if (CollectionUtils.isNotEmpty(userAddrList)) {
            for (int i = 0; i < userAddrList.size(); i++) {
                SUserAddr suAddress = userAddrList.get(i);
                suAddress.setIsDefault(IsDefaultEnum.F.getValue());
                suAddress.setUpdateTime(new Date());
                if (null == isVeneer) {
                    suAddress.setIsVeneer(false);
                } else {
                    suAddress.setIsVeneer(isVeneer);
                }
                this.getSUserAddrMapper().updateByPrimaryKeySelective(suAddress);
            }
        }

        // 更新地址为默认
        int res = this.getSUserAddrMapper().updateByPrimaryKeySelective(record);

        return res;
    }

    private SUserAddr buildUserAddress(UserAddressVo userAddressVo) throws Exception {
        SUserAddr userAddress = new SUserAddr();
        userAddress.setId(userAddressVo.getId());
        userAddress.setUserId(userAddressVo.getUserid());

        String provincecode = userAddressVo.getProvincecode();
        if (StringUtils.isBlank(provincecode)) {
            BArea parent = bAreaService.selectParentByChild(userAddressVo.getCitycode());
            userAddressVo.setProvincecode(parent.getCode());
            userAddressVo.setProvincename(parent.getName());
        }

        userAddress.setProvinceCode(userAddressVo.getProvincecode());
        userAddress.setProvinceName(userAddressVo.getProvincename());
        userAddress.setCityCode(userAddressVo.getCitycode());
        userAddress.setCityName(userAddressVo.getCityname());
        userAddress.setCountyCode(userAddressVo.getCountycode());
        userAddress.setCountyName(userAddressVo.getCountyname());
        userAddress.setUnitName(userAddressVo.getUnitname());
        userAddress.setAddress(userAddressVo.getAddress());
        userAddress.setContact(userAddressVo.getContact());
        userAddress.setPhone(userAddressVo.getPhone());
        userAddress.setAddressType(userAddressVo.getAddresstype());
        userAddress.setIsDefault(userAddressVo.getIsdefault());
        userAddress.setComment(userAddressVo.getComment());
        userAddress.setUpdateTime(new Date());
        userAddress.setIsVeneer(userAddressVo.getIsVeneer() == null ? false : userAddressVo.getIsVeneer());
        return userAddress;
    }

    @Override
    public List<SUserAddr> selectDefaultAddress(Boolean isVeneer, String citycode) throws Exception {
        UserVo user = this.getUserService().getCurrentUserVo();
        logger.info("selectDefaultAddress userid : {}", user.getId());
        SUserAddrExample search = new SUserAddrExample();
        SUserAddrExample.Criteria userAddress = search.createCriteria();
        userAddress.andUserIdEqualTo(user.getId());
        userAddress.andIsDefaultEqualTo(IsDefaultEnum.T.getValue());
        if (null == isVeneer) {
            userAddress.andIsVeneerEqualTo(false);
        } else {
            userAddress.andIsVeneerEqualTo(isVeneer);
        }
        List<SUserAddr> lists = this.getSUserAddrMapper().selectByExample(search);
        List<SUserAddr> sud = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(lists)) {
            if (StringUtils.isNotBlank(citycode)) {
                sud = lists.stream().filter(addr -> addr.getCityCode().equals(citycode)).collect(Collectors.toList());
            } else {
                sud = lists;
            }
        }
        return sud;
    }

    @Override
    public SUserAddr selectUserAddressById(String id) throws Exception {
        logger.info("selectUserAddressById service param : {}", id);
        return this.getSUserAddrMapper().selectByPrimaryKey(Long.parseLong(id));
    }

    private UserService getUserService() {
        return userService;
    }

    public SUserAddrMapper getSUserAddrMapper() {
        return this.sUserAddrMapper;
    }

    @Override
    public Long addUserAddress(String address, String contact, String phone, Boolean isVeneer, String addressType)
            throws Exception {
        logger.info("UserAddressServiceImpl.addUserAdderss param : {}, {}, {}, {}, {}", address, contact, phone,
                isVeneer, addressType);
        UserVo user = this.getUserService().getCurrentUserVo();
        if (null == user) {
            logger.info("current user is null");
            throw new BusinessException("当前登录用户无效");
        }
        if (StringUtils.isBlank(contact)) {
            logger.info("contact is not null");
            throw new BusinessException("联系人不能为空");
        } else if (StringUtils.isBlank(phone)) {
            logger.info("phone is not null");
            throw new BusinessException("联系电话不能为空");
        } else if (StringUtils.isBlank(addressType)) {
            logger.info("addresstype is not null");
            throw new BusinessException("用户地址类型不能为空");
        }
        SUserAddr sAddr = this.buildSUserAddr(address);
        sAddr.setUserId(user.getId());
        sAddr.setAddressType(addressType);
        sAddr.setContact(contact);
        sAddr.setPhone(phone);
        sAddr.setIsVeneer(isVeneer == null ? false : isVeneer);
        SUserAddrExample search = new SUserAddrExample();
        SUserAddrExample.Criteria uaCriteria = search.createCriteria();
        uaCriteria.andUserIdEqualTo(user.getId());
        uaCriteria.andAddressTypeEqualTo(addressType);
        uaCriteria.andIsVeneerEqualTo(sAddr.getIsVeneer());
        int count = this.getSUserAddrMapper().countByExample(search);
        // 如果当前用户只有一条常用地址信息，则设置为默认地址
        if (count == 0) {
            sAddr.setIsDefault(IsDefaultEnum.T.getValue());
        } else {
            sAddr.setIsDefault(IsDefaultEnum.F.getValue());
        }
        this.getSUserAddrMapper().insertSelective(sAddr);
        return sAddr.getId();
    }

    /**
     * 构建用户常用地址
     *
     * @param address
     * @return
     */
    private SUserAddr buildSUserAddr(String address) {
        if (StringUtils.isBlank(address)) {
            logger.info("address is not null");
            throw new BusinessException("用户常用地址必输项不能为空");
        }
        SUserAddrVo suav = JSON.parseObject(address, SUserAddrVo.class);
        if (null == suav) {
            logger.info("suserAddrvo is null");
            throw new BusinessException("用户常用地址对象转换异常");
        }
        if (StringUtils.isBlank(suav.getAddress())) {
            logger.info("address is not null");
            throw new BusinessException("详细地址不能为空");
        } else if (StringUtils.isBlank(suav.getCityName())) {
            logger.info("cityName is not null");
            throw new BusinessException("城市名称不能为空");
        } else if (StringUtils.isBlank(suav.getCountyName())) {
            logger.info("countyName is not null");
            throw new BusinessException("区县名称不能为空");
        } else if (StringUtils.isBlank(suav.getProvinceName())) {
            logger.info("provinceName is not null");
            throw new BusinessException("省名称不能为空");
        }
        SUserAddr sAddr = new SUserAddr();
        try {
            PropertyUtils.copyProperties(sAddr, suav);
            BArea province = this.getBAreaByName(sAddr.getProvinceName(), "1");
            if (null == province) {
                logger.info("convert provinceCode is null");
                throw new BusinessException("省编码转换异常");
            }
            sAddr.setProvinceCode(province.getCode());
            BArea city = this.getBAreaByName(sAddr.getCityName(), "2");
            if (null == city) {
                logger.info("convert cityCode is null");
                throw new BusinessException("市编码转换异常");
            }
            sAddr.setCityCode(city.getCode());
            BArea county = this.getBAreaByName(sAddr.getCountyName(), "3");
            if (null == county) {
                logger.info("convert countyCode is null");
                throw new BusinessException("区县编码转换异常");
            }
            sAddr.setCountyCode(county.getCode());
        } catch (Exception e) {
            logger.error("convert vo is error: {}", e);
        }
        return sAddr;
    }

    /**
     * 根据名称查询编码
     *
     * @param name
     * @param level
     * @return
     */
    private BArea getBAreaByName(String name, String level) {
        BAreaExample province = new BAreaExample();
        province.createCriteria().andNameLike(name).andLevelEqualTo(level).andIsTransportEqualTo(true);
        List<BArea> lists = this.getBAreaMapper().selectByExample(province);
        if (CollectionUtils.isNotEmpty(lists)) {
            return lists.get(0);
        }
        return null;
    }

    @Override
    public int upateUserAddress(String address, String contact, String phone, Boolean isVeneer, String addressType,
                                Long id) throws Exception {
        UserVo user = this.getUserService().getCurrentUserVo();
        if (null == user) {
            logger.info("current user is null");
            throw new BusinessException("当前登录用户无效");
        }
        if (StringUtils.isBlank(contact)) {
            logger.info("contact is not null");
            throw new BusinessException("联系人不能为空");
        } else if (StringUtils.isBlank(phone)) {
            logger.info("phone is not null");
            throw new BusinessException("联系电话不能为空");
        } else if (StringUtils.isBlank(addressType)) {
            logger.info("addresstype is not null");
            throw new BusinessException("用户地址类型不能为空");
        }
        SUserAddr sAddr = this.buildSUserAddr(address);
        sAddr.setUserId(user.getId());
        sAddr.setAddressType(addressType);
        sAddr.setContact(contact);
        sAddr.setPhone(phone);
        sAddr.setId(id);
        sAddr.setIsVeneer(isVeneer == null ? false : isVeneer);
        return this.getSUserAddrMapper().updateByPrimaryKeySelective(sAddr);
    }

}
